home *** CD-ROM | disk | FTP | other *** search
- unit TJTable; {updated on 28/7/96}
-
- interface
-
- uses
- SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
- Forms, Dialogs, DB, DBTables, DbiProcs, DbiTypes;
-
- type
- TPassWdPriv = (prNone,prReadOnly,prModify,prInsert,prInsDel,prFull,prUnknown);
- TPasswdPrivs = set of TPassWdPriv;
- TDbiNameStr = string[DBIMAXNAMELEN];
- TRecNoCap = (rnRecordNum, rnSequenceNum, rnUnsupported);
-
- TjocTable = class(TTable)
- private
- { Private declarations }
- FTblType: array[0..DBIMAXNAMELEN] of char;
- FDeleted: Boolean; {is the record "soft" deleted}
- FRecNoCap: TRecNoCap; {sequence or record numbering supported}
- FBMStable: Boolean; {stable bookmarks?}
- FSoftDelCap: Boolean; {supports "soft" record deletion}
- FRecordNumber: LongInt;
- FShowDeleted: Boolean;
- FBlockSize: Word; {table block size}
- FTableLevel: Word; {table structure version}
- FProtected: Boolean; {is the table password protected?}
- FPasswords: Word; {number of auxiliary passwords}
- FTableRights: TPasswdPrivs;
- FRestructVer: Word; {number of times restructured}
- function GetDeleted: Boolean;
- {$IFNDEF Win32}
- function GetRecordNumber: LongInt;
- {$ENDIF}
- procedure InitTableProperties(const Cursor: HDBICur);
- procedure SetShowDeleted(const Value: Boolean);
- procedure BoolProp(const Value: Boolean);
- procedure WordProp(const Value: Word);
- procedure PasswdProp(const Value: TPasswdPrivs);
- procedure PackPdoxTable;
- function ChkShared: Boolean;
- function GetOpenCursors: Word;
- protected
- { Protected declarations }
- function CreateHandle: HDBICur; override;
- procedure CheckActiveExclusive;
- procedure CheckRemote;
- public
- { Public declarations }
- property Deleted: Boolean read GetDeleted;
- {$IFNDEF Win32}
- property RecNo: LongInt read GetRecordNumber;
- {$ENDIF}
- property StableBookMarks: Boolean read FBMStable;
- property ShowDeleted: Boolean read FShowDeleted write SetShowDeleted default False;
- property IsShared: Boolean read ChkShared;
- property OpenCount: Word read GetOpenCursors;
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure UndeleteRecord;
- procedure GotoRecord(const RecNo: LongInt);
- procedure MoveRelative(const Delta: LongInt);
- procedure Flush;
- procedure Pack;
- {$IFNDEF Win32}
- procedure RenameTable(const RenameTo: string);
- {$ENDIF}
- procedure CopyTable(const Destination: string);
- procedure RebuildIndexes;
- procedure RebuildIndex(const Idx: Integer);
- procedure RebuildNamedIndex(const IdxName: TDbiNameStr);
- published
- { Published declarations }
- property BlockSize: Word read FBlockSize write WordProp;
- property TableLevel: Word read FTableLevel write WordProp;
- property IsProtected: Boolean read FProtected write BoolProp;
- property PasswordCount: Word read FPasswords write WordProp;
- property RestructVersion: Word read FRestructVer write WordProp;
- property TableRights: TPasswdPrivs read FTableRights write PasswdProp;
- end;
-
-
- function TransActive(ADatabase: TDatabase): Boolean;
- procedure Register;
-
- implementation
-
- uses DBConsts;
-
- function TransActive(ADatabase: TDatabase): Boolean;
- var XAct: XInfo;
- begin
- Result := False;
- Check(DbiGetTranInfo(ADatabase.Handle, nil, @XAct));
- Result := (XAct.exState = xsActive);
- end;
-
- constructor TjocTable.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FShowDeleted := False;
- end;
-
- destructor TjocTable.Destroy;
- begin
- inherited Destroy;
- end;
-
- procedure TjocTable.BoolProp(const Value: Boolean);
- begin
- end;
-
- procedure TjocTable.WordProp(const Value: Word);
- begin
- end;
-
- procedure TjocTable.PasswdProp(const Value: TPasswdPrivs);
- begin
- end;
-
- function TjocTable.ChkShared: Boolean;
- var WBool: Bool;
- begin
- Result := False;
- if State = dsInactive then DBError(SDataSetClosed);
- Check(DbiIsTableShared(Handle, WBool));
- Result := Boolean(WBool);
- end;
-
- function TjocTable.GetOpenCursors: Word;
- var szTabName, szDBName: array[0..DBIMAXTBLNAMELEN] of char;
- TempDb: HDbiDb;
- RetCode: DBIResult;
- DBDescr: DBDesc;
- begin
- Result := 0;
- StrPCopy(szDBName, Databasename);
- Check(DbiGetDatabaseDesc(szDBName, @DBDescr));
- Check(DbiOpenDatabase(szDBName, DBDescr.szDBType, dbiREADONLY, dbiOPENSHARED,
- nil, 0, nil, nil, TempDB));
- StrPCopy(szTabName, TableName);
- RetCode := DbiGetTableOpenCount(TempDB, szTabName, FTblType, Result);
- DbiCloseDatabase(TempDB);
- Check(RetCode);
- end;
-
- procedure TjocTable.InitTableProperties(const Cursor: HDBICur);
- const PrivRights : array[TPasswdPriv] of Word =
- (prvNONE, prvREADONLY, prvMODIFY, prvINSERT,
- prvINSDEL, prvFULL, prvUNKNOWN);
- var Props: CURProps;
- i: TPasswdPriv;
- begin
- Check(DbiGetCursorProps(Cursor, Props));
- case Props.iSeqNums of
- 0: FRecNoCap := rnRecordNum;
- 1: FRecNoCap := rnSequenceNum;
- else FRecNoCap := rnUnSupported;
- end;
-
- FSoftDelCap := Props.bSoftDeletes;
- FBMStable := Props.bBookMarkStable;
- FBlockSize := Props.iBlockSize;
- FTableLevel := Props.iTblLevel;
- FProtected := Props.bProtected;
- FPasswords := Props.iPasswords;
- FRestructVer:= Props.iRestrVersion;
-
- FTableRights := [];
- for i := prNone to prUnknown do
- if (Props.eprvRights and PrivRights[i]) = PrivRights[i] then
- Include(FTableRights, i);
-
- StrCopy(FTblType, Props.szTableType);
- end;
-
- procedure TjocTable.SetShowDeleted(const Value: Boolean);
- begin
- if State = dsInactive then DBError(SDataSetClosed);
- if (Value <> FShowDeleted) then
- begin
- if FSoftDelCap then
- begin
- Check(DbiSetProp(HDBIObj(Handle), curSOFTDELETEON, LongInt(Value)));
- FShowDeleted := Value;
- end
- else
- FShowDeleted := False;
- end;
- end;
-
- function TjocTable.CreateHandle: HDBICur;
- begin
- Result := inherited CreateHandle;
- InitTableProperties(Result); {initialise table capabilities flags}
- end;
-
- procedure TjocTable.CheckActiveExclusive;
- begin
- if not(Active and Exclusive) then
- DatabaseError('Table must be opened for exclusive use');
- end;
-
- procedure TjocTable.CheckRemote;
- begin
- if Active and Database.IsSQLBased then
- DatabaseError('Operation not applicable to remote tables');
- end;
-
- function TjocTable.GetDeleted: Boolean;
- var Props: RECProps;
- begin
- Result := False;
- if State = dsInactive then DBError(SDataSetClosed);
-
- if FSoftDelCap then
- try
- UpdateCursorPos;
- Check(DbiGetRecord(Handle, dbiNOLOCK, nil, @Props));
- Result := Props.bDeleteFlag;
- except
- Result := False;
- end;
- end;
-
- {$IFNDEF Win32}
- function TjocTable.GetRecordNumber: LongInt;
- var Props: RECProps;
- begin
- Result := -1;
- UpdateCursorPos;
- Check(DbiGetRecord(Handle, dbiNOLOCK, nil, @Props));
- case FRecNoCap of
- rnSequenceNum: Result := Props.iSeqNum;
- rnRecordNum: Result := Props.iPhyRecNum;
- end;
- end;
- {$ENDIF}
-
- procedure TjocTable.UndeleteRecord;
- var Props: RECProps;
- begin
- if State = dsInactive then DBError(SDataSetClosed);
- if FSoftDelCap then
- begin
- UpdateCursorPos;
- Check(DbiGetRecord(Handle, dbiNOLOCK, nil, @Props));
- Check(DbiUndeleteRecord(Handle));
- end;
- end;
-
- procedure TjocTable.GotoRecord(const RecNo: LongInt);
- begin
- if State = dsInactive then DBError(SDataSetClosed);
- UpdateCursorPos;
- case FRecNoCap of
- rnSequenceNum: Check(DbiSetToSeqNo(Handle, RecNo));
- rnRecordNum: Check(DbiSetToRecordNo(Handle, RecNo));
- end;
- Refresh;
- end;
-
- procedure TjocTable.MoveRelative(const Delta: LongInt);
- begin
- if State = dsInactive then DBError(SDataSetClosed);
- UpdateCursorPos;
- Check(DbiGetRelativeRecord(Handle, Delta, dbiNOLOCK, nil, nil));
- Refresh;
- end;
-
- procedure TjocTable.Flush;
- begin
- if State = dsBrowse then
- Check(DbiSaveChanges(Handle));
- end;
-
- procedure TjocTable.Pack;
- var SaveActive, SaveExcl: Boolean;
- begin
- SaveActive := Active;
- SaveExcl := Exclusive;
-
- try
- Close;
- Exclusive := True;
- Open;
- if StrComp(FTblType,szPARADOX) = 0 then
- PackPdoxTable
- else
- if StrComp(FTblType,szDBASE) = 0 then
- Check(DbiPackTable(Database.Handle, Handle, nil, nil, True))
- else
- DatabaseError(format('Cannot pack this table type (%s)', [FTblType]));
- finally
- Close;
- Exclusive := SaveExcl;
- Active := SaveActive;
- end;
- end;
-
- procedure TjocTable.PackPdoxTable;
- var TblDesc: CRTblDesc;
- hDB: HDbiDb;
- RetCode: DBIResult;
- begin
- FillChar(TblDesc, sizeof(TblDesc), 0);
- StrPCopy(TblDesc.szTblName, TableName);
- StrCopy(TblDesc.szTblType, FTblType);
- TblDesc.bPack := True;
-
- hDB := Database.Handle;
- Close;
- Check(DbiDoRestructure(hDB, 1, @TblDesc, nil, nil, nil, False));
- end;
-
- {$IFNDEF Win32}
- procedure TjocTable.RenameTable(const RenameTo: string);
- var hDB: HDbiDb;
- RenFrom, RenTo: array[0..DBIMAXTBLNAMELEN] of char;
- RetCode: DBIResult;
- SaveActive, SaveExcl: Boolean;
- begin
- SaveActive := Active;
- SaveExcl := Exclusive;
-
- StrPCopy(RenTo, RenameTo);
- StrPCopy(RenFrom, TableName);
-
- try
- Close;
- Exclusive := True;
- Open;
- hDB := Database.Handle;
- Close;
- Check(DbiRenameTable(hDB, RenFrom, nil, RenTo));
- finally
- Close;
- TableName := RenameTo;
- Exclusive := SaveExcl;
- Active := SaveActive;
- end;
- end;
- {$ENDIF}
-
- procedure TjocTable.CopyTable(const Destination: string);
- var CopyFrom, CopyTo: array[0..DBIMAXTBLNAMELEN] of char;
- begin
- if State = dsInactive then DBError(SDataSetClosed);
-
- LockTable(ltReadLock);
- StrPCopy(CopyTo, Destination);
- StrPCopy(CopyFrom, TableName);
-
- Check(DbiCopyTable(Database.Handle, True, CopyFrom, nil, CopyTo));
- UnLockTable(ltReadLock);
- end;
-
- procedure TjocTable.RebuildIndexes;
- var SaveActive, SaveExcl: Boolean;
- begin
- CheckRemote;
- SaveActive := Active;
- SaveExcl := Exclusive;
-
- try
- Close;
- Exclusive := True;
- Open;
- Check(DbiRegenIndexes(Handle));
- finally
- Exclusive := SaveExcl;
- Active := SaveActive;
- end;
- end;
-
- procedure TjocTable.RebuildIndex(const Idx: Integer);
- var IDesc: IDXDesc;
- wIdx: Word;
- SaveActive, SaveExcl: Boolean;
- begin
- CheckRemote;
- if (Idx <= 0) then
- DatabaseError('Invalid index sequence number');
- SaveActive := Active;
- SaveExcl := Exclusive;
-
- IndexDefs.Update;
-
- if (Idx <= IndexDefs.Count) then
- try
- Close;
- Exclusive := True;
- Open;
- wIdx := Word(Idx);
- Check(DbiGetIndexDesc(Handle, wIdx, IDesc));
- Check(DbiRegenIndex(Database.Handle, Handle, nil,
- nil, IDesc.szName, IDesc.szTagName, IDesc.iIndexID));
- finally
- Close;
- Exclusive := SaveExcl;
- Active := SaveActive;
- end else
- DataBaseError('Index not found');
- end;
-
- procedure TjocTable.RebuildNamedIndex(const IdxName: TDbiNameStr);
- var IDesc: IDXDesc;
- Idx: Integer;
- wIdx: Word;
- SaveActive, SaveExcl: Boolean;
-
- begin
- CheckRemote;
- SaveActive := Active;
- SaveExcl := Exclusive;
- IndexDefs.Update;
- Idx := IndexDefs.IndexOf(IdxName);
-
- if (Idx >= 0) then
- try
- Close;
- Exclusive := True;
- Open;
- wIdx := Succ(Idx);
- Check(DbiGetIndexDesc(Handle, wIdx, IDesc));
- Check(DbiRegenIndex(Database.Handle, Handle, nil,
- nil, IDesc.szName, IDesc.szTagName, IDesc.iIndexId));
- finally
- Close;
- Exclusive := SaveExcl;
- Active := SaveActive;
- end else
- DatabaseError(format('Index %s not found', [IdxName]));
- end;
-
- procedure Register;
- begin
- RegisterComponents('JOC', [TjocTable]);
- end;
-
- end.
-